#include "directoryOperation.h"

int stackInit(pathStack_t* cur){
    char sql[1024] = {0};
    sprintf(sql,"select id from userfile where owner_id = %d and parent_directory_id = -1",cur->owner_id);
    int qret = mysql_query(cur->mysql,sql);
    if(qret != 0){
        fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
        return -1;
    }
    MYSQL_RES* result = mysql_store_result(cur->mysql);
    if(mysql_num_rows(result) == 1){
        MYSQL_ROW row = mysql_fetch_row(result);
        int id = atoi(row[0]);
        cur->stack[(cur->top)++] = id;
        return 0;
    }
    else{
        printf("database error\n");
        return -1;
    }
}

int stackRestore(pathStack_t* cur){
    memcpy(cur->stack,cur->restoreStack,sizeof(int)*MAX_STACK_SIZE);
    cur->top = cur->top_r;
    return 0;
}

int get_filename(fileMetaData_t* meta,pathStack_t* cur){
    char* token;
    char* saveptr;
    char* str = strdup(meta->path);
    char filename[50];
    for(int i = 0;;i++,str = NULL){                                                                            
        token = strtok_r(str,"/",&saveptr);
        if(token == NULL){
            break;
        }   
        if(strcmp(token,".") == 0){ 
            continue;
        }   
        if(strcmp(token,"..") == 0){ 
            --(cur->top);
            if(cur->top == 0){
                printf("path invalid\n");
                return -1;
            }
            continue;
        }
        (cur->top)++;
        bzero(filename,sizeof(filename));
        strcpy(filename,token);
    }
    strcpy(meta->filename,filename);
    return 0;
}

int stackPath(fileMetaData_t* meta,pathStack_t* cur){
    char* token;
    char* saveptr;
    char* str = strdup(meta->path);
    char sql[1024];
    int id;
    char filename[50];
    memcpy(cur->restoreStack,cur->stack,sizeof(int)*MAX_STACK_SIZE);
    cur->top_r = cur->top;
    for(int i = 0;;i++,str = NULL){                                                                            
        token = strtok_r(str,"/",&saveptr);
        if(token == NULL){
            break;
        }   
        if(strcmp(token,".") == 0){ 
            continue;
        }   
        if(strcmp(token,"..") == 0){ 
            --(cur->top);
            if(cur->top == 0){
                printf("path invalid\n");
                return -1;
            }
            continue;
        }
        bzero(filename,50);
        strcpy(filename,token);
        bzero(sql,1024);
        sprintf(sql,"select is_deleted,id from userfile where owner_id = %d and parent_directory_id = %d and filename = '%s'",cur->owner_id,cur->stack[cur->top-1],filename);
        int qret = mysql_query(cur->mysql,sql);
        if(qret != 0){
            fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
            return -1;
        }
        MYSQL_RES* result = mysql_store_result(cur->mysql);
        if(mysql_num_rows(result) != 0){
            MYSQL_ROW row = mysql_fetch_row(result);
            if(atoi(row[0]) == 1){
                printf("path invalid\n");
                return -1;
            }
            id = atoi(row[1]);
            cur->stack[(cur->top)++] = id;
        }
        else{
            printf("path invalid\n");
            return -1;
        }
    }
    return 0;
}

int pri_pwd(char* path,pathStack_t* cur){
    if(cur->top <= 0){
        printf("path invalid\n");
        return -1;
    }
    else{
        int id = cur->stack[cur->top-1];
        char sql[1024] = {0};
        sprintf(sql,"select filepath from userfile where id = %d",id);
        int qret = mysql_query(cur->mysql,sql);
        if(qret != 0){
            fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
            return -1;
        }
        MYSQL_RES* result = mysql_store_result(cur->mysql);
        MYSQL_ROW row = mysql_fetch_row(result);
        mysql_free_result(result);
        strcpy(path,row[0]);
        return 0;
    }
}

int pri_cd(bool path_type,fileMetaData_t* meta,pathStack_t* cur){
    printf("BEGIN cd-------------------------------------\n");
    printf("choooseoption|filemeta  filename is %s and path is %s\n",meta->filename,meta->path);
    printf("psatck top is %d\n",cur->stack[cur->top-1]);
    memcpy(cur->restoreStack,cur->stack,sizeof(int)*MAX_STACK_SIZE);
    cur->top_r = cur->top;
    if(path_type){
        cur->top = 1;
        char* token;
        char* saveptr;
        char* str = strdup(meta->path);
        printf("strdup函数结果：meta->path:%s复制给str:%s\n",meta->path,str);
        char sql[1024];
        int id;
        for(int i = 0;;i++,str = NULL){
            printf("分割前str是:%s\n",str);
            token = strtok_r(str,"/",&saveptr);
            printf("分割后str is %s,token is %s\n",str,token);
            if(token == NULL){
                break;
            }
            bzero(sql,1024);
            sprintf(sql,"select is_deleted,id from userfile where owner_id = %d and parent_directory_id = %d and filename = '%s'",cur->owner_id,cur->stack[cur->top-1],token);
            printf("cd执行的sql为：%s\n",sql);
            int qret = mysql_query(cur->mysql,sql);
            if(qret != 0){
                fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
                stackRestore(cur);
                return -1;
            }
            MYSQL_RES* result = mysql_store_result(cur->mysql);
            if(mysql_num_rows(result) != 0){
                MYSQL_ROW row = mysql_fetch_row(result);
                if(atoi(row[0]) == 1){
                    printf("This file or directory does not exist\n");
                    return -1;
                }
                id = atoi(row[1]);
                cur->stack[(cur->top)++] = id;
            }
            else{
                printf("path invalid\n");
                return -1;
            }
            mysql_free_result(result);
        }
    } 
    else{
        int ret = stackPath(meta,cur);
        if(ret == -1){
            stackRestore(cur);
            printf("AFTER cd-------------------------------------\n");
            printf("choooseoption|filemeta  filename is %s and path is %s\n",meta->filename,meta->path);
            printf("psatck top is %d\n",cur->stack[cur->top-1]);
            return -1;
        }
    }
    printf("AFTER cd-------------------------------------\n");
    printf("choooseoption|filemeta  filename is %s and path is %s\n",meta->filename,meta->path);
    printf("psatck top is %d\n",cur->stack[cur->top-1]);
    return 0;
}

//多次mkdir时会出现filename和filepath路径和其他的重叠
int pri_mkdir(bool path_type,fileMetaData_t* meta,pathStack_t* cur){
    printf("BEGIN mkdir-------------------------------------\n");
    printf("choooseoption|filemeta  filename is %s and path is %s\n",meta->filename,meta->path);
    printf("psatck top is %d\n",cur->stack[cur->top-1]);    
    memcpy(cur->restoreStack,cur->stack,sizeof(int)*MAX_STACK_SIZE);
    cur->top_r = cur->top;
    char sql[1024];
    int id;
    if(path_type){
        get_filename(meta,cur);
        cur->top = 1;
    }
    else{
        int gret = get_filename(meta,cur);
        if(gret == -1){
            printf("get filename failed\n");
            return -1;
        }
        stackRestore(cur);
    }
    char* token;
    char* saveptr;                                                                                       
    char* str = strdup(meta->path);
    for(int i = 0;;i++,str = NULL){    
        token = strtok_r(str,"/",&saveptr);
        if(strcmp(token,meta->filename) == 0){ 
            break;
        }   
        if(strcmp(token,".") == 0){ 
            continue;
        }   
        if(strcmp(token,"..") == 0){
            --(cur->top);
            if(cur->top == 0){                                                                           
                printf("path invalid\n");
                stackRestore(cur);
                return -1;
            }
            continue;
        }
        bzero(sql,1024);
        sprintf(sql,"select is_deleted,id from userfile where owner_id = %d and parent_directory_id = %d and filename = '%s'",cur->owner_id,cur->stack[cur->top-1],token); 
        printf("mkdir 执行的查询sql为：%s\n",sql);
        int qret = mysql_query(cur->mysql,sql);
        if(qret != 0){
            fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
            stackRestore(cur);
            return -1;
        }
        MYSQL_RES* result = mysql_store_result(cur->mysql);
        if(mysql_num_rows(result) != 0){
            MYSQL_ROW row = mysql_fetch_row(result);
            if(atoi(row[0]) == 1){
                printf("path invalid\n");
                stackRestore(cur);
                return -1;
            }
            id = atoi(row[1]);
            cur->stack[(cur->top)++] = id;
        }
        else{
            printf("path invalid\n");
            stackRestore(cur);
            return -1;
        }
        mysql_free_result(result);
    }
    meta->parent_directory_id = cur->stack[cur->top-1];
    if(!path_type){
        char temp[256] = {0};
        printf("这是mkdir调用的pwd函数\n");
        pri_pwd(temp,cur);
        if(cur->top == 1){
            sprintf(meta->path,"%s%s",temp,meta->filename);
        }else{
            sprintf(meta->path,"%s/%s",temp,meta->filename);
        }

    }
    int ret = insert_into(cur->mysql,meta);
    printf("AFTER mkdir-------------------------------------\n");
    printf("choooseoption|filemeta  filename is %s and path is %s\n",meta->filename,meta->path);
    printf("psatck top is %d\n",cur->stack[cur->top-1]);
    if(ret == -1){
        printf("insert into fileTable failed\n");
        return -1;
    }
    return 0;
}

int pri_rmdir(bool path_type,fileMetaData_t* meta,pathStack_t* cur){
    memcpy(cur->restoreStack,cur->stack,sizeof(int)*MAX_STACK_SIZE);
    cur->top_r = cur->top;
    char sql[1024];
    int parent_directory_id;
    if(path_type){
        bzero(sql,1024);
        sprintf(sql,"select is_deleted,id from userfile where owner_id = %d and filepath = '%s'",cur->owner_id,meta->path);
        int qret = mysql_query(cur->mysql,sql);
        if(qret != 0){
            fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
            return -1;
        }
        MYSQL_RES* result = mysql_store_result(cur->mysql);
        if(mysql_num_rows(result) != 0){
            MYSQL_ROW row = mysql_fetch_row(result);
            if(atoi(row[0]) == 1){
                printf("This directory does not exist\n");
                return -1;
            }
            parent_directory_id = atoi(row[1]);
        }
        else{
            printf("This directory does not exist\n");
            return -1;
        }
    }
    else{
        int ret = stackPath(meta,cur);
        if(ret == -1){
            stackRestore(cur);
            return -1;
        }
        if(cur->top <= 1){
            printf("path invalid\n");
            stackRestore(cur);
            return -1;
        }
        parent_directory_id = cur->stack[cur->top-1];
        stackRestore(cur);
    }
    bzero(sql,1024);
    sprintf(sql,"select id from userfile where owner_id = %d and parent_directory_id = %d",cur->owner_id,parent_directory_id);
    int qret = mysql_query(cur->mysql,sql);
    if(qret != 0){
        fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
        return -1;
    }
    MYSQL_RES* result = mysql_store_result(cur->mysql);
    if(mysql_num_rows(result) > 0){
        printf("directory not empty\n");
        return -1;
    }
    meta->file_id = parent_directory_id;
    int ret = delete_from(cur->mysql,meta);
    if(ret == -1){
        printf("delete from fileTable failed\n");
        return -1;
    }
    return 0;
}

int pri_ls(bool path_type,fileMetaData_t* meta,pathStack_t* cur,char* res){
    memcpy(cur->restoreStack,cur->stack,sizeof(int)*MAX_STACK_SIZE);
    cur->top_r = cur->top;
    char sql[1024];
    int parent_directory_id;
    if(meta->path == NULL){
        parent_directory_id = cur->stack[cur->top-1];
    }
    else if(path_type){
        bzero(sql,1024);
        sprintf(sql,"select is_deleted,id from userfile where owner_id = %d and filepath = '%s'",cur->owner_id,meta->path);
        int qret = mysql_query(cur->mysql,sql);
        if(qret != 0){
            fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
            return -1;
        }
        MYSQL_RES* result = mysql_store_result(cur->mysql);
        if(mysql_num_rows(result) != 0){
            MYSQL_ROW row = mysql_fetch_row(result);
            if(atoi(row[0]) == 1){
                printf("path invalid\n");
                return -1;
            }
            parent_directory_id = atoi(row[1]);
        }
        else{
            printf("path invalid\n");
            return -1;
        }
    }
    else{
        int ret = stackPath(meta,cur);
        if(ret == -1){
            stackRestore(cur);
            return -1;
        }
        parent_directory_id = cur->stack[cur->top-1];
        stackRestore(cur);
    }
    bzero(sql,1024);
    sprintf(sql,"select filename from userfile where owner_id = %d and parent_directory_id = %d",cur->owner_id,parent_directory_id);
    int qret = mysql_query(cur->mysql,sql);
    if(qret != 0){
        fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
        return -1;
    }
    MYSQL_RES* result = mysql_store_result(cur->mysql);
    for(unsigned long i = 0;i < mysql_num_rows(result);i++){
        MYSQL_ROW row = mysql_fetch_row(result);
        strcat(res,row[0]);
        strcat(res,"\t");
    }
    return 0;
}

int pri_remove(bool path_type,fileMetaData_t* meta,pathStack_t* cur){
    memcpy(cur->restoreStack,cur->stack,sizeof(int)*MAX_STACK_SIZE);
    cur->top_r = cur->top;
    char sql[1024];
    if(path_type){
        bzero(sql,1024);
        sprintf(sql,"select is_deleted,id from userfile where owner_id = %d and filepath = '%s'",cur->owner_id,meta->path);
        int qret = mysql_query(cur->mysql,sql);
        if(qret != 0){
            fprintf(stderr,"mysql_query : %s\n",mysql_error(cur->mysql));
            return -1;
        }
        MYSQL_RES* result = mysql_store_result(cur->mysql);
        if(mysql_num_rows(result) != 0){
            MYSQL_ROW row = mysql_fetch_row(result);
            if(atoi(row[0]) == 1){
                printf("This file does not exist\n");
                return -1;
            }
            meta->file_id = atoi(row[0]);
        }
        else{
            printf("path invalid\n");
            return -1;
        }
    }
    else{
        int ret = stackPath(meta,cur);
        if(ret == -1){
            stackRestore(cur);
            return -1;
        }
        meta->file_id = cur->stack[cur->top-1];
        stackRestore(cur);
    }
    int ret = delete_from(cur->mysql,meta);
    if(ret == -1){
        printf("delete from fileTable failed\n");
        return -1;
    }
    return 0;
}
